import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import {randomNum} from "@/utils/czr-util";

let scene, camera, renderer
let width, height
const deepLen = 1400
const cubes: any = {
  earth: null,
}
const clouds: any = []
const stars = [
  {
    color: [0.6, 100, 0.75],
    color2Direction: 1,
    size: 50,
    material: null,
    geometry: null,
    cube: null,
  },
  {
    color: [0, 0, 1],
    color2Direction: 1,
    size: 10,
    material: null,
    geometry: null,
    cube: null
  }
]
let startMoveOffset = 0
const init = (dom) => {
  width = dom.clientWidth
  height = dom.clientHeight
  initScene()
  initCamera()
  initRenderer(dom)
  initAnimate()
  initLight()
  initSceneCube()
}
const initScene = () => {
  scene = new THREE.Scene()
  scene.fog = new THREE.Fog('#000000', 0, 10000);
  scene.background = new THREE.CubeTextureLoader().setPath(import.meta.env.BASE_URL + 'src/views/three/test/').load([
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
  ])
  //  背景
  const bgImg = new URL('./login-bg.png', import.meta.url).href
  new THREE.TextureLoader().load(bgImg, (texture) => {
    const geometry = new THREE.BoxGeometry(width, height, deepLen)
    const material = new THREE.MeshBasicMaterial({
      map: texture,
      side: THREE.BackSide
    })
    scene.add(new THREE.Mesh(geometry, material))
  })
}
const initCamera = () => {
  const fov = 15
  const dis = width / 2 / Math.tan(Math.PI / (180 / fov))
  camera = new THREE.PerspectiveCamera(fov, width / height, 1, 30000);
  camera.position.set(0, 0, Math.floor(dis - deepLen / 2))
  // 为了更清晰的看到物体的运动轨迹，可以添加坐标轴辅助对象AxesHelper
  // 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
  const axesHelper = new THREE.AxesHelper(width);
  scene.add(axesHelper);
  const cameraHelper = new THREE.CameraHelper(camera);
  scene.add(cameraHelper)
}
const initRenderer = (dom) => {
  renderer = new THREE.WebGLRenderer({ canvas: dom, antialias: true });
  renderer.setSize(width, height);
}
const initLight = () => {
  const light = new THREE.AmbientLight('#ffffff', 3)
  scene.add(light)
  const earthLight = new THREE.PointLight('#2713d0', 3000, 0, 1)
  earthLight.position.set(-width / 4 + 50, 200, -100)
  scene.add(earthLight)
  scene.add(new THREE.PointLightHelper(earthLight, 10))
}
const initAnimate = () => {
  // const controls = new OrbitControls(camera, renderer.domElement);
  // controls.enableDamping  = true //启用阻尼（惯性）
  // controls.dampingFactor = 0.05 //阻尼惯性有多大
  // controls.autoRotate = false // 自动旋转
  // controls.autoRotateSpeed = 1.0 //围绕目标旋转的速度将有多快
  // controls.enablePan = false //启用或禁用摄像机平移
  // controls.enableRotate = false //启用或禁用摄像机水平或垂直旋转
  const animate = () => {
    // controls.update()
    requestAnimationFrame(animate)
    cubes.earth?.rotateY(0.01)
    renderStarMove()
    clouds.forEach(v => v.render?.())
    renderer.render( scene, camera )
  }
  animate()
}
const initSceneCube = () => {
  startMoveOffset = camera.position.z
  //  地球
  const earthImg = new URL('./earth_bg.png', import.meta.url).href
  new THREE.TextureLoader().load(earthImg, (texture) => {
    const geometry = new THREE.SphereGeometry(50, 64, 32)
    const material: any = new THREE.MeshPhongMaterial({
      map: texture,
    })
    cubes.earth = new THREE.Mesh(geometry, material)
    cubes.earth.position.set(-width / 4, 200, -200)
    scene.add(cubes.earth)
  })
  //  星星
  const starImg1 = new URL('./starflake1.png', import.meta.url).href
  new THREE.TextureLoader().load(starImg1, (texture) => {
    const vertices: any = []
    for (let i = 0; i < 1500; i++) {
      const x = THREE.MathUtils.randFloatSpread(width)
      const y = randomNum(0, height / 2)
      const z = randomNum(-deepLen / 2, camera.position.z)
      vertices.push(x, y, z)
    }
    const geometry = new THREE.BufferGeometry()
    const material: any = new THREE.PointsMaterial({
      size: stars[0].size,
      map: texture,
      blending: THREE.AdditiveBlending,
      transparent: true,
      depthTest: true
    })
    material.color.setHSL(...stars[0].color)
    stars[0].material = material
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3))
    stars[0].geometry = geometry
    const star = new THREE.Points(geometry, material)
    star.position.z = -camera.position.z - deepLen / 2
    scene.add(star)
    stars[0].cube = star
  })
  const starImg2 = new URL('./starflake2.png', import.meta.url).href
  new THREE.TextureLoader().load(starImg2, (texture) => {
    const vertices: any = []
    for (let i = 0; i < 1500; i++) {
      const x = THREE.MathUtils.randFloatSpread(width)
      const y = randomNum(0, height / 2)
      const z = randomNum(-deepLen / 2, camera.position.z)
      vertices.push(x, y, z)
    }
    const geometry = new THREE.BufferGeometry()
    const material: any = new THREE.PointsMaterial({
      size: stars[1].size,
      map: texture,
      blending: THREE.AdditiveBlending,
      transparent: true,
      depthTest: true
    })
    material.color.setHSL(...stars[1].color)
    stars[1].material = material
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3))
    stars[1].geometry = geometry
    const star = new THREE.Points(geometry, material)
    star.position.z = -camera.position.z - deepLen / 2
    scene.add(star)
    stars[1].cube = star
  })
  //  星云
  const arr = [
    [300, 400, [
      new THREE.Vector3(-width / 10, 0, -deepLen / 2),
      new THREE.Vector3(-width / 4, height / 8, 0),
      new THREE.Vector3(-width / 4, 0, camera.position.z),
    ], 0.001],
    [200, 100, [
      new THREE.Vector3(width / 8, height / 8, -deepLen / 2),
      new THREE.Vector3(width / 8, height / 8, camera.position.z),
    ], 0.005]
  ]
  arr.forEach(v => {
    const cube = initSceneCloud(v[0], v[1])
    clouds.push({
      cube: cube,
      render: renderCloudMove(cube, v[2], v[3])
    })
  })
}
const renderStarMove = () => {
  startMoveOffset += 10
  if (startMoveOffset >= camera.position.z) {
    startMoveOffset = -camera.position.z - deepLen / 2
  }
  stars.forEach(v => {
    if (v.cube) {
      if (v.color[2] >= 1 || v.color[2] <= 0.5) {
        v.color2Direction *= -1
      }
      v.color[2] += v.color2Direction * 0.002
      v.material?.color.setHSL(...v.color)
      v.cube.position.z = startMoveOffset
    }
  })
}
const initSceneCloud = (w, h) => {
  const cloudImg = new URL('./cloud.png', import.meta.url).href
  const texture = new THREE.TextureLoader().load(cloudImg)
  const geometry = new THREE.PlaneGeometry(w, h)
  const material: any = new THREE.MeshBasicMaterial({
    map: texture,
    blending: THREE.AdditiveBlending,
    transparent: true,
    depthTest: false
  })
  const cube = new THREE.Mesh(geometry, material)
  scene.add(cube)
  return cube
}
const renderCloudMove = (cube, routes, speed) => {
  let pro = 0
  const curve = new THREE.CatmullRomCurve3(routes)
  return () => {
    if (pro <= 1) {
      pro += speed
      const point = curve.getPoint(pro)
      if (point && point.x) {
        cube.position.set(point.x, point.y, point.z)
      }
    } else {
      pro = 0
    }
  }
}
export {
  init
}